package com.czk.queue.delayqueuedemo;

import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * 延时队列
 *
 * @Author:ChenZhangKun
 * @Date: 2021/12/9 14:03
 */
public class CustomDelayQueue {
    private static DelayQueue<MyDelay> delayQueue = new DelayQueue();

    public static void main(String[] args) throws InterruptedException {
        producer();
        consumer();
    }

    private static void producer() {
        delayQueue.add(new MyDelay(3000, "消息一"));
        delayQueue.add(new MyDelay(5000, "消息二"));

    }

    private static void consumer() throws InterruptedException {
        System.out.println("开始执行时间：" +
                DateFormat.getDateTimeInstance().format(new Date()));
        while (!delayQueue.isEmpty()) {
            System.out.println(delayQueue.take());
        }
        System.out.println("结束执行时间：" +
                DateFormat.getDateTimeInstance().format(new Date()));
    }

    static class MyDelay implements Delayed {
        long delayTime = System.currentTimeMillis();
        private String msg;

        public MyDelay(long delayTime, String msg) {
            // 设置演示时间
            this.delayTime = delayTime + this.delayTime;
            // 消息
            this.msg = msg;
        }

        // 获取延时时间
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }

        // 队列里元素的排序依据
        @Override
        public int compareTo(Delayed o) {
            if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
                // 正序
                return 1;
            } else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) {
                // 逆序
                return -1;
            } else {
                return 0;
            }
        }

        @Override
        public String toString() {
            return this.msg;
        }
    }
}
